package com.framework.service.common.impl;

import com.alibaba.fastjson.JSONObject;
import com.framework.common.enums.annex.AnnexGroupEnum;
import com.framework.common.enums.annex.AnnexTypeEnum;
import com.framework.common.enums.result.ResultEnum;
import com.framework.common.model.response.R;
import com.framework.common.util.annex.AnnexFilterUtil;
import com.framework.common.util.minio.MinioUtil;
import com.framework.common.util.other.NumeralUtil;
import com.framework.common.util.other.SymbolUtil;
import com.framework.common.util.redis.RedisKeyUtil;
import com.framework.mapper.common.AnnexMapper;
import com.framework.mapper.common.GroupMapper;
import com.framework.mapper.common.TypeMapper;
import com.framework.model.common.vo.AnnexVo;
import com.framework.model.common.vo.GroupVo;
import com.framework.model.system.vo.SystemUserVo;
import com.framework.service.base.BaseService;
import com.framework.service.common.AnnexService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 龘鵺
 * @version 1.0
 * @className com.framework.service.common.impl.AnnexServiceImpl
 * @description 附件业务接口实现类
 * @datetime 2024-07-05 17:01:06
 */
@Service("annexServiceImpl")
public class AnnexServiceImpl extends BaseService implements AnnexService {
    private Logger log = LoggerFactory.getLogger(AnnexServiceImpl.class);
    @Value("${custom.minio.bucketName}")
    private String bucketName;
    @Value("${custom.minio.annex-address}")
    private String annexAddress;
    @Autowired
    private AnnexMapper annexMapper;
    @Autowired
    private GroupMapper groupMapper;
    @Autowired
    private TypeMapper typeMapper;
    @Autowired
    private MinioUtil minioUtil;

    /**
     * @param id 1 编号
     * @return com.framework.model.common.vo.AnnexVo
     * @title 根据编号查询附件
     * @description 根据编号查询附件
     * @author 龘鵺
     * @datetime 2024-07-05 17:01:06
     * @version 1.0
     */
    @Override
    public AnnexVo getByIdParam(Long id) {
        AnnexVo row = new AnnexVo();
        row.setId(id);
        SystemUserVo systemUserVo = getUser();
        row.setGtaeOperaterStatus(NumeralUtil.POSITIVE_ONE);
        AnnexVo p = annexMapper.selectByParam(row);
        if (p == null) {
            return new AnnexVo();
        }
        return p;
    }

    /**
     * @param row 1 附件类
     * @return com.framework.common.model.response.R
     * @title 新增附件
     * @description 新增附件
     * @author 龘鵺
     * @datetime 2024-07-05 17:01:06
     * @version 1.0
     */
    @Override
    @Transactional
    public R<?> save(AnnexVo row) {
        SystemUserVo systemUserVo = getUser();
        Long userId = systemUserVo.getId();
        Date date = new Date();
        row.setCreateId(userId);
        row.setCreateTime(date);
        row.setOperaterId(userId);
        row.setOperaterTime(date);
        row.setOperaterStatus(NumeralUtil.POSITIVE_ONE);
        annexMapper.insertSelective(row);
        return R.ok();
    }

    /**
     * @param row 1 附件类
     * @return com.framework.common.model.response.R
     * @title 编辑附件
     * @description 编辑附件
     * @author 龘鵺
     * @datetime 2024-07-05 17:01:06
     * @version 1.0
     */
    @Override
    @Transactional
    public R<?> edit(AnnexVo row) {
        SystemUserVo systemUserVo = getUser();
        AnnexVo queryParam = new AnnexVo();
        queryParam.setId(row.getId());
        queryParam.setGtaeOperaterStatus(NumeralUtil.POSITIVE_ONE);
        queryParam = annexMapper.selectByParam(queryParam);
        if (queryParam == null) {
            return R.fail("编辑信息不存在!");
        }
        Long userId = systemUserVo.getId();
        Date date = new Date();
        row.setOperaterTime(date);
        row.setOperaterId(userId);
        row.setOperaterStatus(NumeralUtil.POSITIVE_TWO);
        annexMapper.updateByPrimaryKeySelective(row);
        return R.ok();
    }

    /**
     * @param id 1 编号
     * @return com.framework.common.model.response.R
     * @title 删除附件
     * @description 删除附件
     * @author 龘鵺
     * @datetime 2024-07-05 17:01:06
     * @version 1.0
     */
    @Override
    @Transactional
    public R<?> delete(Long id) {
        AnnexVo row = new AnnexVo();
        SystemUserVo systemUserVo = getUser();
        Long userId = systemUserVo.getId();
        Date date = new Date();
        row.setId(id);
        row.setOperaterTime(date);
        row.setOperaterId(userId);
        row.setOperaterStatus(NumeralUtil.NEGATIVE_ONE);
        annexMapper.delete(row);
        return R.ok();
    }

    /**
     * @param idList 1 编号集合
     * @return com.framework.common.model.response.R
     * @title 批量删除附件
     * @description 批量删除附件
     * @author 龘鵺
     * @datetime 2024-07-05 17:01:06
     * @version 1.0
     */
    @Override
    @Transactional
    public R<?> batchDeleteList(List<Long> idList) {
        AnnexVo row = new AnnexVo();
        SystemUserVo systemUserVo = getUser();
        Long userId = systemUserVo.getId();
        Date date = new Date();
        row.setIdList(idList);
        row.setOperaterTime(date);
        row.setOperaterId(userId);
        row.setOperaterStatus(NumeralUtil.NEGATIVE_ONE);
        //annexMapper.deleteList(row);
        return R.ok();
    }

    /**
     * @param row 1 附件类
     * @return java.util.List<com.framework.model.common.vo.AnnexVo>
     * @title 查询附件集合
     * @description 查询附件集合
     * @author 龘鵺
     * @datetime 2024-07-05 17:01:06
     * @version 1.0
     */
    @Override
    public List<AnnexVo> findByList(AnnexVo row) {
        SystemUserVo systemUserVo = getUser();
        row.setGtaeOperaterStatus(NumeralUtil.POSITIVE_ONE);
        List<AnnexVo> list = annexMapper.findByList(row);
        return list;
    }

    /**
     * @param row 1 附件类
     * @return com.framework.common.model.response.R
     * @title 分页查询附件列表
     * @description 分页查询附件列表
     * @author 龘鵺
     * @datetime 2024-07-05 17:01:06
     * @version 1.0
     */
    @Override
    public R<?> findParamPageList(AnnexVo row) {
        SystemUserVo systemUserVo = getUser();
        row.setGtaeOperaterStatus(NumeralUtil.POSITIVE_ONE);
        int count = annexMapper.findPageListCount(row);
        if (count == NumeralUtil.POSITIVE_ZERO) {
            return R.ok();
        }
        List<AnnexVo> list = annexMapper.findPageList(row);
        return R.ok(list, count);
    }

    /**
     * @param delUploads   1 取消关联图片
     * @param systemUserId 2 操作用户
     * @param date         3 操作时间
     * @title 取消关联
     * @description 取消关联
     * @author 龘鵺
     * @datetime 2024-07-09 13:46:44
     */
    @Override
    @Transactional
    public void clearAssociation(List<Long> delUploads, Long systemUserId, Date date) {
        if (delUploads == null || delUploads.size() < NumeralUtil.POSITIVE_ONE) {
            return;
        }
        AnnexVo row = new AnnexVo();
        row.setIdList(delUploads);
        row.setOperaterId(systemUserId);
        row.setOperaterTime(date);
        row.setEnableStatus(NumeralUtil.POSITIVE_TWO);
        row.setOperaterStatus(NumeralUtil.POSITIVE_TWO);
        row.setRelationStatus(NumeralUtil.NEGATIVE_ONE);
        annexMapper.updateRelationStatusList(row);
    }

    /**
     * @param annexGroupEnum 1 分组枚举
     * @param file           2 上传对象
     * @param userId         3 用户编号
     * @param date           4 上传时间
     * @return com.framework.common.model.response.R
     * @title 图片上传
     * @description 图片上传-可能有问题
     * @author 龘鵺
     * @datetime 2024-07-09 20:00:58
     */
    @Override
    public R<?> imageUpload(AnnexGroupEnum annexGroupEnum, MultipartFile file, Long userId, Date date) throws Exception {
        GroupVo groupVo = new GroupVo();
        groupVo.setCode(annexGroupEnum.getCode());
        groupVo.setEnableStatus(NumeralUtil.POSITIVE_ONE);
        groupVo.setGtaeOperaterStatus(NumeralUtil.POSITIVE_ZERO);
        groupVo = groupMapper.selectByParam(groupVo);
        if (groupVo == null) {
            return R.fail(ResultEnum.CODE20000);
        }
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(SymbolUtil.NO_INPUT_METHOD_PERIOD) + NumeralUtil.POSITIVE_ONE);
        long time = System.currentTimeMillis();
        String newName = time + SymbolUtil.NO_INPUT_METHOD_PERIOD + suffix;
        StringBuilder path = new StringBuilder(bucketName);
        path.append(SymbolUtil.NO_INPUT_METHOD_FORWARD_SLASH);
        path.append(groupVo.getCode());
        path.append(SymbolUtil.NO_INPUT_METHOD_FORWARD_SLASH);
        path.append(newName);

        String objectName = groupVo.getCode() + SymbolUtil.NO_INPUT_METHOD_FORWARD_SLASH + newName;
        minioUtil.uploadFile(file.getInputStream(), bucketName, objectName);

        AnnexVo row = new AnnexVo();
        row.setCreateId(userId);
        row.setCreateTime(date);
        row.setOperaterId(userId);
        row.setOperaterTime(date);
        row.setOperaterStatus(NumeralUtil.POSITIVE_ONE);
        row.setEnableStatus(NumeralUtil.POSITIVE_ONE);
        row.setGroupCode(annexGroupEnum.getCode());
        row.setGroupId(groupVo.getId());
        row.setOldName(file.getOriginalFilename());
        row.setSuffix(suffix);
        row.setNewName(newName);
        row.setAnnexType(AnnexTypeEnum.code1.getValue());
        row.setPath(path.toString());

        annexMapper.insertSelective(row);
        JSONObject data = new JSONObject();
        data.put("url", path);
        data.put("annexId", row.getId());
        return R.ok(data);
    }


    /**
     * @param row 1 上传类
     * @return com.framework.common.model.response.R
     * @title 富文本编辑器上传
     * @description 富文本编辑器上传-可能有问题
     * @author 龘鵺
     * @datetime 2024-08-19 16:04:27
     */
    @Override
    public R<?> wangeditorImageUpload(AnnexVo row) throws Exception {
        String originalName = row.getFile().getOriginalFilename();
        int one = originalName.lastIndexOf(SymbolUtil.NO_INPUT_METHOD_PERIOD);
        if (one < NumeralUtil.POSITIVE_ZERO) {
            return R.fail("文件格式错误!");
        }
        String suffix = originalName.substring((one + NumeralUtil.POSITIVE_ONE));
        StringBuilder suffixStr = new StringBuilder();
        for (String item : AnnexFilterUtil.imageMatchFormats) {
            if (item.equalsIgnoreCase(suffix)) {
                suffixStr = null;
                break;
            }
            suffixStr.append(item).append(",");
        }
        if (suffixStr != null) {
            suffixStr.deleteCharAt(suffixStr.length() - NumeralUtil.POSITIVE_ONE);
            return R.fail("只支持" + suffixStr + "等格式上传!");
        }

        AnnexGroupEnum annexGroupEnum = AnnexGroupEnum.wangeditor;
        GroupVo groupVo = new GroupVo();
//        String code = annexGroupEnum.getCode().toLowerCase() + minioSuffix;
        String code = annexGroupEnum.getCode();
//        String code = annexGroupEnum.getCode() + SymbolUtil.NO_INPUT_METHOD_MINUS_SIGN + type.getTypeCode().toLowerCase() + minioSuffix;
        groupVo.setCode(code);
        groupVo.setEnableStatus(NumeralUtil.POSITIVE_ONE);
        groupVo.setGtaeOperaterStatus(NumeralUtil.POSITIVE_ZERO);
        groupVo = groupMapper.selectByParam(groupVo);
        if (groupVo == null) {
            return R.fail(ResultEnum.CODE20000);
        }

//        minioUtil.createBucket(code);
        String name = System.currentTimeMillis() + SymbolUtil.NO_INPUT_METHOD_PERIOD + suffix;
        SystemUserVo systemUserVo = getUser();
        Date date = new Date();
        Long userId = systemUserVo.getId();
        row.setOldName(originalName);
        row.setNewName(name);
        row.setCreateId(userId);
        row.setCreateTime(date);
        row.setOperaterId(userId);
        row.setOperaterTime(date);
        row.setOperaterStatus(NumeralUtil.POSITIVE_ONE);
        row.setEnableStatus(NumeralUtil.POSITIVE_ONE);
        row.setGroupCode(groupVo.getCode());
        row.setGroupId(groupVo.getId());
        row.setSuffix(suffix);
        row.setAnnexType(AnnexTypeEnum.code1.getValue());

//        StringBuilder path = new StringBuilder(code);
//        path.append(SymbolUtil.NO_INPUT_METHOD_FORWARD_SLASH);
//        path.append(name);
//        row.setPath(path.toString());
//        minioUtil.uploadFile(row.getFile().getInputStream(), code, name);

        StringBuilder path = new StringBuilder(bucketName);
        path.append(SymbolUtil.NO_INPUT_METHOD_FORWARD_SLASH);
        path.append(groupVo.getCode());
        path.append(SymbolUtil.NO_INPUT_METHOD_FORWARD_SLASH);
        path.append(name);
        row.setPath(path.toString());
        String objectName = groupVo.getCode() + SymbolUtil.NO_INPUT_METHOD_FORWARD_SLASH + name;
        minioUtil.uploadFile(row.getFile().getInputStream(), bucketName, objectName);

        annexMapper.insertSelective(row);
        Map<String, String> map = new HashMap<String, String>();
        map.put("url", annexAddress + path);
        return R.ok(map);
    }

    /**
     * @return com.framework.common.model.response.R
     * @title 获取附件前缀地址
     * @description 获取附件前缀地址
     * @author 龘鵺
     * @datetime 2024-08-19 16:04:27
     */
    @Override
    public R<?> getAnnexUrl() {
        return R.ok(annexAddress);
    }

    /**
     * @param id 1 编号
     * @return com.framework.common.model.response.R
     * @title 启用|禁用，角色
     * @description 启用|禁用，角色
     * @author 龘鵺
     * @datetime 2024-06-19 09:34:28
     * @version 1.0
     */
    @Override
    @Transactional
    public R<?> enable(Long id) throws Exception {
        String timeKey = RedisKeyUtil.getObjKey("ANNEX_ENABLE_KEY", "ANNEX_ENABLE_KEY", id.toString());
        long expireNum = redisUtil.getExpire(timeKey);
        if (expireNum > NumeralUtil.POSITIVE_ZERO) {
            return R.fail("操作频繁,请" + expireNum + "秒后重试!");
        }
        AnnexVo row = new AnnexVo();
        SystemUserVo systemUserVo = getUser();
        Long userId = systemUserVo.getId();
        row.setId(id);
        row.setGtaeOperaterStatus(NumeralUtil.POSITIVE_ZERO);
        row = annexMapper.selectByRow(row);
        if (row == null) {
            return R.fail("信息不存在!");
        }
        redisUtil.setString(timeKey, NumeralUtil.STRING_POSITIVE_ZERO, NumeralUtil.POSITIVE_THIRTY);
        Date date = new Date();
        AnnexVo updateRow = new AnnexVo();
        updateRow.setId(id);
        updateRow.setOperaterId(userId);
        updateRow.setOperaterTime(date);
        updateRow.setOperaterStatus(NumeralUtil.POSITIVE_TWO);
        updateRow.setEnableStatus(row.getEnableStatus().intValue() == NumeralUtil.POSITIVE_TWO ? NumeralUtil.POSITIVE_ONE : NumeralUtil.POSITIVE_TWO);
        annexMapper.updateByPrimaryKeySelective(updateRow);
        return R.ok();
    }
}